using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymod
{
    public class ModelTemplate : IModelTemplate
    {
        private readonly Type _modelType;
        private readonly IDictionary<string, object> _state;

        public ModelTemplate(Type modelType, IDictionary<string, object> initialModelState)
        {
            if (initialModelState == null) throw new System.ArgumentNullException("initialModelState");
            if (modelType == null) throw new System.ArgumentNullException("modelType");
            _modelType = modelType;
            _state = initialModelState;
        }

        public IModel CreateModel(object value, IDictionary<string, object> modelState)
        {
            if (value == null) throw new System.ArgumentNullException("value");

            var instance = (IModel)Activator.CreateInstance(_modelType);

            //Clone the state... some invokers may have state.
            var state = _state.ToDictionary(kp => kp.Key, kp => (kp.Value is ICloneable) ? ((ICloneable)kp.Value).Clone() : kp.Value);
            //Merge model state with the initial state (ModelState overrides the initial state)
            foreach (var kp in modelState)
            {
                state[kp.Key] = kp.Value;
            }

            instance.Initialize(value, state);
            return instance;
        }
    }
}
